const { User, MemberLevel, MemberUpgrade, PointsTransaction, sequelize } = require('../models')
const pointsService = require('./pointsService')
const logger = require('../utils/logger')
const { Op } = require('sequelize')

class MemberService {
  /**
   * 初始化默认会员等级
   */
  async initDefaultLevels() {
    try {
      const existingLevels = await MemberLevel.count()
      if (existingLevels > 0) {
        return // 已有等级配置，不需要初始化
      }

      const defaultLevels = [
        {
          level: 1,
          name: '普通会员',
          min_points: 0,
          max_points: 999.99,
          discount_rate: 0,
          privileges: {
            features: ['基础兑换'],
            description: '享受基础兑换服务'
          },
          color: '#999999',
          description: '新用户默认等级，享受基础服务'
        },
        {
          level: 2,
          name: '银牌会员',
          min_points: 1000,
          max_points: 4999.99,
          discount_rate: 0.05,
          privileges: {
            features: ['5%折扣', '优先客服'],
            description: '享受5%折扣优惠和优先客服服务'
          },
          color: '#C0C0C0',
          description: '累计积分达到1000分可升级为银牌会员'
        },
        {
          level: 3,
          name: '金牌会员',
          min_points: 5000,
          max_points: 19999.99,
          discount_rate: 0.1,
          privileges: {
            features: ['10%折扣', '专属客服', '生日特权'],
            description: '享受10%折扣优惠、专属客服和生日特权'
          },
          color: '#FFD700',
          description: '累计积分达到5000分可升级为金牌会员'
        },
        {
          level: 4,
          name: '钻石会员',
          min_points: 20000,
          max_points: null,
          discount_rate: 0.15,
          privileges: {
            features: ['15%折扣', '专属客服', '生日特权', '免费配送'],
            description: '享受15%折扣优惠、专属客服、生日特权和免费配送'
          },
          color: '#B9F2FF',
          description: '累计积分达到20000分可升级为钻石会员'
        }
      ]

      await MemberLevel.bulkCreate(defaultLevels)
      logger.info('默认会员等级初始化完成')

    } catch (error) {
      logger.error('初始化默认会员等级失败:', error)
      throw error
    }
  }

  /**
   * 获取所有会员等级
   * @returns {Promise<Array>} 会员等级列表
   */
  async getAllLevels() {
    try {
      const levels = [
        {
          id: 1,
          name: '普通会员',
          icon: '🥉',
          minPoints: 0,
          benefits: ['基础打印服务', '积分兑换商品', '客服支持']
        },
        {
          id: 2,
          name: '银牌会员',
          icon: '🥈',
          minPoints: 100,
          benefits: ['打印9.5折优惠', '专属客服', '优先处理', '生日礼品']
        },
        {
          id: 3,
          name: '金牌会员',
          icon: '🥇',
          minPoints: 500,
          benefits: ['打印9折优惠', '免费加急服务', '专属活动', '月度礼品']
        },
        {
          id: 4,
          name: '钻石会员',
          icon: '💎',
          minPoints: 1000,
          benefits: ['打印8.5折优惠', '免费配送', 'VIP专线', '季度大礼包']
        },
        {
          id: 5,
          name: '至尊会员',
          icon: '👑',
          minPoints: 2000,
          benefits: ['打印8折优惠', '专属定制', '一对一服务', '年度豪礼']
        }
      ]

      return levels
    } catch (error) {
      logger.error('获取会员等级列表失败:', error)
      throw new Error('获取会员等级列表失败')
    }
  }

  /**
   * 根据积分计算会员等级
   * @param {number} totalPoints - 累计积分
   * @returns {Promise<Object>} 会员等级信息
   */
  async calculateMemberLevel(totalPoints) {
    try {
      const level = await MemberLevel.findOne({
        where: {
          is_active: true,
          min_points: { [Op.lte]: totalPoints },
          [Op.or]: [
            { max_points: null },
            { max_points: { [Op.gte]: totalPoints } }
          ]
        },
        order: [['level', 'DESC']]
      })

      if (!level) {
        // 如果没有找到匹配的等级，返回最低等级
        return await MemberLevel.findOne({
          where: { is_active: true },
          order: [['level', 'ASC']]
        })
      }

      return level
    } catch (error) {
      logger.error('计算会员等级失败:', error)
      throw error
    }
  }

  /**
   * 检查并更新用户会员等级
   * @param {number} userId - 用户ID
   * @returns {Promise<Object>} 更新结果
   */
  async checkAndUpdateMemberLevel(userId) {
    const transaction = await sequelize.transaction()
    
    try {
      const user = await User.findByPk(userId, { transaction })
      if (!user) {
        throw new Error('用户不存在')
      }

      // 根据累计积分计算应有等级
      const targetLevel = await this.calculateMemberLevel(user.total_earned_points)
      
      if (!targetLevel) {
        throw new Error('无法确定会员等级')
      }

      // 检查是否需要升级
      if (user.member_level >= targetLevel.level) {
        await transaction.commit()
        return {
          upgraded: false,
          currentLevel: user.member_level,
          targetLevel: targetLevel.level
        }
      }

      // 获取当前等级信息
      const currentLevelInfo = await MemberLevel.findOne({
        where: { level: user.member_level, is_active: true }
      })

      // 更新用户等级
      await user.update({
        member_level: targetLevel.level,
        member_level_updated_at: new Date()
      }, { transaction })

      // 记录升级历史
      const upgradeRecord = await MemberUpgrade.create({
        user_id: userId,
        from_level: user.member_level,
        to_level: targetLevel.level,
        from_level_name: currentLevelInfo ? currentLevelInfo.name : '未知等级',
        to_level_name: targetLevel.name,
        points_at_upgrade: user.total_earned_points,
        upgrade_type: 'auto',
        reward_points: this.calculateUpgradeReward(targetLevel.level),
        notes: '系统自动升级'
      }, { transaction })

      // 发放升级奖励积分
      if (upgradeRecord.reward_points > 0) {
        await pointsService.addPoints(userId, upgradeRecord.reward_points, {
          type: 'member_upgrade',
          description: `会员升级奖励 - 升级至${targetLevel.name}`,
          relatedId: upgradeRecord.id
        })
      }

      await transaction.commit()

      logger.info(`用户会员等级升级: ${userId}, ${user.member_level} -> ${targetLevel.level}`)

      return {
        upgraded: true,
        fromLevel: user.member_level,
        toLevel: targetLevel.level,
        fromLevelName: currentLevelInfo ? currentLevelInfo.name : '未知等级',
        toLevelName: targetLevel.name,
        rewardPoints: upgradeRecord.reward_points,
        upgradeRecord
      }

    } catch (error) {
      await transaction.rollback()
      logger.error('检查更新会员等级失败:', error)
      throw error
    }
  }

  /**
   * 计算升级奖励积分
   * @param {number} level - 等级
   * @returns {number} 奖励积分
   */
  calculateUpgradeReward(level) {
    const rewards = {
      2: 50,   // 银牌会员奖励50积分
      3: 100,  // 金牌会员奖励100积分
      4: 200   // 钻石会员奖励200积分
    }
    
    return rewards[level] || 0
  }

  /**
   * 获取用户会员信息
   * @param {number} userId - 用户ID
   * @returns {Promise<Object>} 会员信息
   */
  async getUserMemberInfo(userId) {
    try {
      const user = await User.findByPk(userId)

      if (!user) {
        throw new Error('用户不存在')
      }

      // 根据用户积分计算当前等级
      const userPoints = parseFloat(user.points) || 0
      const currentLevel = this.calculateLevelByPoints(userPoints)
      const nextLevel = this.getNextLevel(currentLevel.id)

      // 计算升级进度
      let upgradeProgress = null
      if (nextLevel) {
        const progressPoints = userPoints - currentLevel.minPoints
        const totalNeededPoints = nextLevel.minPoints - currentLevel.minPoints
        const progressPercentage = Math.min((progressPoints / totalNeededPoints) * 100, 100)
        
        upgradeProgress = {
          currentPoints: userPoints,
          nextLevelPoints: nextLevel.minPoints,
          neededPoints: Math.max(nextLevel.minPoints - userPoints, 0),
          progressPercentage: Math.round(Math.max(progressPercentage, 0))
        }
      }

      return {
        user: {
          id: user.id,
          nickname: user.nickname,
          avatar_url: user.avatar_url,
          points: user.points,
          member_level: user.memberLevel
        },
        currentLevel,
        nextLevel,
        upgradeProgress
      }

    } catch (error) {
      logger.error('获取用户会员信息失败:', error)
      throw error
    }
  }

  /**
   * 根据积分计算会员等级
   * @param {number} points - 用户积分
   * @returns {Object} 会员等级信息
   */
  calculateLevelByPoints(points) {
    const levels = [
      { id: 1, name: '普通会员', icon: '🥉', minPoints: 0, benefits: ['基础打印服务', '积分兑换商品', '客服支持'] },
      { id: 2, name: '银牌会员', icon: '🥈', minPoints: 100, benefits: ['打印9.5折优惠', '专属客服', '优先处理', '生日礼品'] },
      { id: 3, name: '金牌会员', icon: '🥇', minPoints: 500, benefits: ['打印9折优惠', '免费加急服务', '专属活动', '月度礼品'] },
      { id: 4, name: '钻石会员', icon: '💎', minPoints: 1000, benefits: ['打印8.5折优惠', '免费配送', 'VIP专线', '季度大礼包'] },
      { id: 5, name: '至尊会员', icon: '👑', minPoints: 2000, benefits: ['打印8折优惠', '专属定制', '一对一服务', '年度豪礼'] }
    ]

    // 找到用户当前等级
    let currentLevel = levels[0]
    for (let i = levels.length - 1; i >= 0; i--) {
      if (points >= levels[i].minPoints) {
        currentLevel = levels[i]
        break
      }
    }

    return {
      ...currentLevel,
      description: `享受${currentLevel.name}专属权益`
    }
  }

  /**
   * 获取下一等级
   * @param {number} currentLevelId - 当前等级ID
   * @returns {Object|null} 下一等级信息
   */
  getNextLevel(currentLevelId) {
    const levels = [
      { id: 1, name: '普通会员', icon: '🥉', minPoints: 0 },
      { id: 2, name: '银牌会员', icon: '🥈', minPoints: 100 },
      { id: 3, name: '金牌会员', icon: '🥇', minPoints: 500 },
      { id: 4, name: '钻石会员', icon: '💎', minPoints: 1000 },
      { id: 5, name: '至尊会员', icon: '👑', minPoints: 2000 }
    ]

    const nextLevelIndex = levels.findIndex(level => level.id === currentLevelId) + 1
    return nextLevelIndex < levels.length ? levels[nextLevelIndex] : null
  }

  /**
   * 获取用户升级历史
   * @param {number} userId - 用户ID
   * @param {Object} options - 查询选项
   * @returns {Promise<Object>} 升级历史
   */
  async getUserUpgradeHistory(userId, options = {}) {
    try {
      const {
        page = 1,
        limit = 20
      } = options

      const offset = (page - 1) * limit

      const result = await MemberUpgrade.findAndCountAll({
        where: { user_id: userId },
        limit: parseInt(limit),
        offset,
        order: [['created_at', 'DESC']]
      })

      return {
        upgrades: result.rows,
        pagination: {
          total: result.count,
          page: parseInt(page),
          limit: parseInt(limit),
          pages: Math.ceil(result.count / limit)
        }
      }

    } catch (error) {
      logger.error('获取用户升级历史失败:', error)
      throw new Error('获取升级历史失败')
    }
  }

  /**
   * 计算订单折扣
   * @param {number} userId - 用户ID
   * @param {number} originalAmount - 原始金额
   * @returns {Promise<Object>} 折扣信息
   */
  async calculateOrderDiscount(userId, originalAmount) {
    try {
      const user = await User.findByPk(userId, {
        include: [
          {
            model: MemberLevel,
            as: 'memberLevelInfo'
          }
        ]
      })

      if (!user || !user.memberLevelInfo) {
        return {
          originalAmount,
          discountRate: 0,
          discountAmount: 0,
          finalAmount: originalAmount
        }
      }

      const discountRate = user.memberLevelInfo.discount_rate || 0
      const discountAmount = originalAmount * discountRate
      const finalAmount = originalAmount - discountAmount

      return {
        originalAmount,
        discountRate,
        discountAmount,
        finalAmount,
        memberLevel: user.memberLevelInfo
      }

    } catch (error) {
      logger.error('计算订单折扣失败:', error)
      throw error
    }
  }

  /**
   * 获取会员统计信息
   * @returns {Promise<Object>} 统计信息
   */
  async getMemberStatistics() {
    try {
      const levels = await MemberLevel.findAll({
        where: { is_active: true },
        order: [['level', 'ASC']]
      })

      const statistics = []
      
      for (const level of levels) {
        const userCount = await User.count({
          where: { member_level: level.level }
        })
        
        statistics.push({
          level: level.level,
          name: level.name,
          userCount,
          color: level.color
        })
      }

      const totalUsers = await User.count()
      const totalUpgrades = await MemberUpgrade.count()

      return {
        levelStatistics: statistics,
        totalUsers,
        totalUpgrades
      }

    } catch (error) {
      logger.error('获取会员统计信息失败:', error)
      throw new Error('获取会员统计信息失败')
    }
  }
}

module.exports = new MemberService()